package es.xpt.ysf.commons.person;

import static javax.ejb.TransactionAttributeType.REQUIRED;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;


import es.xpt.ysf.YSFException;
import es.xpt.ysf.commons.person.model.Person;
import es.xpt.ysf.dao.DAOException;
import es.xpt.ysf.logging.LogManager;
import es.xpt.ysf.utils.UUID;


@Stateless(name = "PersonSession")
@TransactionAttribute(REQUIRED)
public class PersonSessionBean implements PersonSession { // NO_UCD
		
	@Resource
	private SessionContext context;
	
	@EJB PersonSession ps;
	
	public PersonSessionBean() {
	}
	
	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.person.PersonSession#getEntityPeople(java.lang.String, java.lang.String)
	 */
	public List<Person> getEntityPeople(String entity, String entityId) 
			throws YSFException{
		if (entity == null || entity.trim().length()<=0)
			throw new NullPointerException("entity");
		
		if (entityId == null || entityId.trim().length()<=0)
			throw new NullPointerException("entityId");
		
		PersonDAOFactory f = null;
		try {
			f = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = f.getPersonDAO();
			return dao.getEntityPeople(entityId, entity);
		} finally {
			if (f != null) f.release();
		}
	}
	
	
	public Person getEntityPersonByRole(String entity, String entityId,
			String role) throws YSFException {

		if (entity == null || entity.trim().length()<=0)
			throw new NullPointerException("entity");
		
		if (entityId == null || entityId.trim().length()<=0)
			throw new NullPointerException("entityId");
		
		if (role == null || role.trim().length()<=0)
			throw new NullPointerException("role");
		
		PersonDAOFactory f = null;
		try {
			f = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = f.getPersonDAO();
			return dao.getEntityPersonByRole(entityId, entity, role);
		} finally {
			if (f != null) f.release();
		}

	}


	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.person.PersonSession#addEntityPerson(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
	 */
	public void addEntityPerson(String entityId, String entity, String personId, String role) throws YSFException {
		if (entity == null || entity.trim().length()<=0)
			throw new NullPointerException("entity");
		
		if (entityId == null || entityId.trim().length()<=0)
			throw new NullPointerException("entityId");
		
		if (personId == null || personId.trim().length()<=0)
			throw new NullPointerException("personId");
		
		if (role == null || role.trim().length()<=0)
			throw new NullPointerException("role");
		
		PersonDAOFactory f = null;
		try {
			f = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = f.getPersonDAO();
			dao.addEntityPerson(entityId, entity, personId, role);
		} finally {
			if (f != null) f.release();
		}
	}
	

	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.person.PersonSession#removeEntityPerson(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
	 */
	public void removeEntityPerson(String entityId, String entity, String personId, String role) throws YSFException {
		if (entity == null || entity.trim().length()<=0)
			throw new NullPointerException("entity");
		
		if (entityId == null || entityId.trim().length()<=0)
			throw new NullPointerException("entityId");
		
		if (personId == null || personId.trim().length()<=0)
			throw new NullPointerException("personId");
		
		if (role == null || role.trim().length()<=0)
			throw new NullPointerException("role");
		
		PersonDAOFactory f = null;
		try {
			f = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = f.getPersonDAO();
			dao.removeEntityPerson(entityId, entity, personId, role);
		} finally {
			if (f != null) f.release();
		}

	}
	

	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.person.PersonSession#searchPerson(java.lang.String)
	 */
	public List<Person> searchPerson(String name) throws YSFException {
		
		PersonDAOFactory f = null;
		try {
			f = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = f.getPersonDAO();
			return dao.searchPerson(name);
		} finally {
			if (f != null) f.release();
		}

	}
	
	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.person.PersonSession#searchPerson(es.xpt.ysf.commons.person.model.Person)
	 */
	public List<Person> searchPerson(Person person) throws YSFException {
		
		PersonDAOFactory f = null;
		try {
			f = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = f.getPersonDAO();
			return dao.searchPerson(person);
		} finally {
			if (f != null) f.release();
		}

	}
	
	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.person.PersonSession#searchDependentEntities(java.lang.String)
	 */
	public ArrayList<String[]>  searchDependentEntities(String personId) throws YSFException {
		if (personId == null || personId.trim().length()<=0)
			throw new NullPointerException("personId");
		
		PersonDAOFactory f = null;
		try {
			f = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = f.getPersonDAO();
			return dao.searchDependentEntities(personId);
		} finally {
			if (f != null) f.release();
		}

	}

	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.person.PersonSession#searchEntityDependences(java.lang.String,java.lang.String)
	 */
	public List<String> searchEntityDependences(String personId,String entity) throws YSFException {
		if (entity == null || entity.trim().length()<=0)
		throw new NullPointerException("entity");
	
		if (personId == null || personId.trim().length()<=0)
		throw new NullPointerException("personId");
	
	PersonDAOFactory f = null;
	try {
		f = new PersonDAOFactory(context.getCallerPrincipal());
		PersonDAO dao = f.getPersonDAO();
		return dao.searchEntityDependences(personId,entity);
	} finally {
		if (f != null) f.release();
	}

	}
	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.person.PersonSession#getPerson(java.lang.String)
	 */
	public Person getPerson(String id) throws YSFException {
		
		if (id == null || id.trim().length()<=0)
			throw new NullPointerException("id");

		PersonDAOFactory f = null;
		try {
			f = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = f.getPersonDAO();
			return dao.getPerson(id);
		} finally {
			if (f != null)
				f.release();
		}
	}


	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.person.PersonSession#updatePerson(es.xpt.ysf.commons.person.model.Person)
	 */
	public void updatePerson(Person person) throws YSFException {
		if ( person==null )
			throw new NullPointerException ("person");
		
		person.check();

		PersonDAOFactory f = null;
		try {
			f = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = f.getPersonDAO();
			dao.update(person);
		} finally {
			if (f != null) f.release();
		}
	}



	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.person.PersonSession#insertPerson(es.xpt.ysf.commons.person.model.Person)
	 */
	public Person insertPerson(Person person) throws YSFException {
		if ( person==null )
			throw new NullPointerException ("person");
		
		person.setId(UUID.randomUUID());
		person.check();

		PersonDAOFactory f = null;
		try {
			f = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = f.getPersonDAO();
			dao.insert(person);
			return person;
		} catch (YSFException e) {
			context.setRollbackOnly();
			return null;
		} finally {
			if (f != null)
				f.release();
		}
	}
	

	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.person.PersonSession#insertPerson(es.xpt.ysf.commons.person.model.Person, java.lang.String, java.lang.String)
	 */
	public Person insertPerson(Person person, String entity, String entityId) throws YSFException {		
		if ( person==null )
			throw new NullPointerException ("person");
		
		if (entity == null || entity.trim().length()<=0)
			throw new NullPointerException("entity");
		
		if (entityId == null || entityId.trim().length()<=0)
			throw new NullPointerException("entityId");
		
		if ( person.getRole() == null || person.getRole().getCode()==null || person.getRole().getCode().length() <= 0 ) 
			throw new NullPointerException("person.role");
		
		person.setId(UUID.randomUUID());
		person.check();
		
		PersonDAOFactory f = null;
		try {
			f = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = f.getPersonDAO();
			dao.insert(person);
			dao.addEntityPerson(entityId, entity, person.getId(), person.getRole().getCode());
			return person;
		} catch (YSFException e) {
			context.setRollbackOnly();
			return null;
		} finally {
			if (f != null)
				f.release();
		}
	}


	/* (non-Javadoc)
	 * @see es.xpt.ysf.commons.person.PersonSession#deletePerson(java.lang.String)
	 */
	public void deletePerson(String id) throws YSFException {
		if (id == null || id.trim().length()<=0)
			throw new NullPointerException("id");
		
		PersonDAOFactory f = null;
		try {
			f = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = f.getPersonDAO();
			dao.delete(id);
		} finally {
			if (f != null)
				f.release();
		}

	}

	public List<String> deleteBatchPeople(List<String> listCodePeople) throws YSFException{
		if (listCodePeople==null)
			throw new NullPointerException("listCodePeople");
		
			if (listCodePeople.size()>0){
				List<String> listMessages = new ArrayList<String>();
				try{
					 ps.deleteBatchPeopleNewTransactional(listCodePeople);
				}catch (DAOException e){
					for ( String code: listCodePeople) {
						try {
							ps.deletePersonNewTransactional(code);
						}catch (DAOException daoe) {
							listMessages.add(daoe.getMessage());
							listMessages.add((daoe.getParameters()!=null) ? (String)daoe.getParameters()[0]: "");
						}
					}
				}
				return listMessages;
		}else
			return null;
	}

	@TransactionAttribute (TransactionAttributeType.REQUIRES_NEW)
	public void deleteBatchPeopleNewTransactional(List<String> listPerson) throws YSFException{
		if ( listPerson==null)
			throw new NullPointerException("listPerson");
		
		if( listPerson.size()>0){
			PersonDAOFactory r = null;
			
			try {
				r = new PersonDAOFactory(context.getCallerPrincipal());
				PersonDAO dao = r.getPersonDAO();					 
				dao.deleteBatchPeople(listPerson);	
			} catch (DAOException e) {
				context.setRollbackOnly();
				throw e;
			} finally {
				if (r != null) r.release();
			} 
		}
	}

	@TransactionAttribute (TransactionAttributeType.REQUIRES_NEW)
	public void deletePersonNewTransactional(String codePerson) throws YSFException{
	if (codePerson==null)
		throw new NullPointerException("codePerson");

			PersonDAOFactory r = null;
		
		try {
			r = new PersonDAOFactory(context.getCallerPrincipal());
			PersonDAO dao = r.getPersonDAO();
		 	dao.delete(codePerson);
		} catch (DAOException e) {
			context.setRollbackOnly();
		 	String[] params = new String[1];
		 	params[0]= codePerson;
		 	LogManager.getLog(this.getClass()).debug(e.getMessage()+" :id: "+codePerson);
			throw new DAOException(e.getMessage(),params);
		} finally {
			if (r != null) r.release();
		} 
}

}
